#include <iostream>
#include <stdio.h>
#include <string>

class A
{
public:
    A() {}
    virtual ~A()
    {
        std::cout << "~A\n";
    }

    virtual void printf() {}

private:
    int sex;

protected:
    std::string name;
};

// 不在派生类成员函数内，不能访问基类保护成员
class B : public A
{
public:
    ~B()
    {
        std::cout << "~B\n";
    }

    void printf()
    {
        std::cout << name.c_str() << "\n";
    }

    void setName(const char *str)
    {
        name = str;
    }
};

class VirtualA
{

public:
    virtual void func()
    {
        std::cout << "T::func\n";
    }
};

class VirtualB : public VirtualA
{
public:
    virtual void func()
    {
        std::cout << "T2::func\n";
    }
};
// 类大小
void TestClassSizeof()
{
    std::cout << "A sizeof " << sizeof(A) << "\n";
    std::cout << "VirtualB sizeof " << sizeof(VirtualB) << "\n";
}

// 虚函数表

void TestVirtualTable()
{
    VirtualB *p = new VirtualB;
    long lVptrP = 0, lVptrAddr1 = 0;
    memcpy(&lVptrP, p, 4);
    std::cout << lVptrP << "----------" << lVptrAddr1 << "\n";
    VirtualB *p1 = new VirtualB;
    memcpy(&lVptrAddr1, p1, 4);
    std::cout << lVptrP << "----------" << lVptrAddr1 << "\n";
    printf("%llx %llx\n", lVptrP, lVptrAddr1); // 编译阶段保证每个类只有一个虚函数表，
}

int main(int argc, char const *argv[])
{
    // 保护类型
    B *b = new B;
    b->setName("hello");
    // delete b;
    // b = nullptr;
    std::cout << "----------->\n";
    A *a = (A *)b;
    a->printf();
    delete a;
    a = nullptr;
    // delete b;
    // b = nullptr;
    std::cout << "----------->\n";
    // const std::type_info &binfo = typeid(b);
    // std::cout << binfo.name() << " | " << binfo.hash_code() << "\n";
    return 0;
}
